﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Scope8
{
    /// <summary>
    /// Diese Klasse repräsentiert einen Imageserver des Aperio. 
    /// </summary>
    class AperioImageServer : ImageServer
    {
        /// <summary>
        /// Standardkonstruktor der Klasse. hier automatisch die ServerURL festgelegt.
        /// </summary>
        public AperioImageServer()
        {
            ServerURL = AperioConstants.aperioURL_XMLrootFolderRSS;
        }

        /// <summary>
        /// Liefert eine Stringrepraesentation der Klasse zurück.
        /// </summary>
        /// <returns>die Stringrepraesentation der Klasse </returns>
        public override String ToString()
        {
            String returnString = "Aperio";

            return returnString;
        }

        /// <summary>
        /// Überschreibt die Methode der geerbten Klasse. Liefert zu der serverurl eine Liste von Sldies zurück, die aus der serverurl extrahiert wurde.
        /// </summary>
        /// <returns>eine Liste von Slides</returns>
        public override async Task<List<Slide>> getAvaiableSlides()
        {
            List<String> listOfDirectoryNames = new List<String>();
            String rootFolder = AperioConstants.aperioURL_pure + AperioConstants.aperioURL_RSSFolder;
            
            List<String> folderNames = await getFolderList(rootFolder);

            foreach (String directoryName in folderNames)
            {
                if (!directoryName.Contains(".svs") && !directoryName.Contains("Digital Slides: //images2.aperio.com/"))
                {
                    listOfDirectoryNames.Add(directoryName);
                }
            }

            int index = 0;
            while (index < listOfDirectoryNames.Count && index < 10)
            {
                String directoryName = listOfDirectoryNames[index];

                //Rss von http://images2.aperio.com/VSC493/Aug2012/view.apml?listview=0& enthält fehler
                if (!directoryName.Equals("VSC493/Aug2012"))
                {                    
                    List<String> listofOneDirectody = await getFolderList(AperioConstants.aperioURL_pure + directoryName + "/" + AperioConstants.aperioURL_RSSFolder);
                    foreach (String newdirectoryName in listofOneDirectody)
                    {
                        String searchDirectory = directoryName + "/" + newdirectoryName;
                        listOfDirectoryNames.Add(searchDirectory);
                    }
                    index++;
                }
            }

            //Durchsuche nach Slides
            foreach (String directory in listOfDirectoryNames)
            {
                //Fehler mit BigTiff
                if (!directory.Contains("BigTIFF + JPEG2000 - BigTIFF sample images with JPEG2000 compression"))
                {
                    String statsFolderXMLurl = AperioConstants.aperioURL_pure + directory + AperioConstants.aperioURL_XMLContent;
                    List<AperioSlide> listofAperioSlides = await getImageListFromFolder(statsFolderXMLurl, directory + "/");
                    foreach (AperioSlide anEntry in listofAperioSlides)
                    {
                        AvaibleSlides.Add(anEntry);
                    }
                }
            }

            return AvaibleSlides;
        }

        /// <summary>
        /// Analysiert die Rss-datei der angegebenen url auf Ordner und gibt diese als Liste zurück.
        /// </summary>
        /// <param name="rootRssUrl">die vollständige URL der Rss: Beispiel: http://images2.aperio.com/rss.xml?chost=images2.aperio.com&csis=0 </param>
        /// <returns>enthält eine Liste von Einträgen von Ordnern des übergebenen Ordners. der übergebene Ordner enthält demnach diese Ordner.   </returns>
        public async Task<List<String>> getFolderList(String fullAperioFolder_RSS)
        {
            XmlReader reader = await getXmlReader(fullAperioFolder_RSS);
            List<String> listOfDirectoryNames = new List<String>();

            Boolean titleTagfound = false;
            while (reader.Read())
            {
                switch (reader.NodeType)
                {

                    case XmlNodeType.Element:
                        if (reader.Name.Equals("title"))
                        {
                            titleTagfound = true;
                        }
                        break;
                    case XmlNodeType.Text:
                        if (titleTagfound)
                        {
                            if (!reader.Value.Contains(";") && !reader.Value.Contains(".") && !reader.Value.Contains(".svs") && !reader.Value.Contains(".tif") && !reader.Value.Contains(".jpg") && !reader.Value.Contains(".ndpi") && !reader.Value.Contains("Digital Slides: //images2.aperio.com/"))
                            {
                                listOfDirectoryNames.Add(reader.Value);
                            }                            
                        }
                        break;
                    case XmlNodeType.EndElement:
                        if (reader.Name.Equals("title"))
                        {
                            titleTagfound = false;
                        }
                        break;
                }
            }

            return listOfDirectoryNames;
        }

        /// <summary>
        /// Analysiert die übergebene XML Datei auf Slides und gibt diese als Liste zurück.
        /// </summary>
        /// <param name="fullAperioFolderURL_XML">die vollständige URL der XML-Datei. Beipspiel: http://images2.aperio.com/stats.xml </param>
        /// <param name="folder">der Ordner, der untersucht werden soll</param>
        /// <returns>liefert eine Liste von AperioSlides zurück, die die Slides des Perio enthalten sollen</returns>
        public async Task<List<AperioSlide>> getImageListFromFolder(String fullAperioFolderURL_XML, String folder)
        {
            XmlReader reader = await getXmlReader(fullAperioFolderURL_XML);

            List<String> xmlTagValueList = new List<String>();
            AperioSlide oneAperioSlideObj = new AperioSlide();

            List<AperioSlide> listOfAperioSlides = new List<AperioSlide>();

            Boolean imageTagfound = false;
            while (reader.Read())
            {
                switch (reader.NodeType)
                {

                    case XmlNodeType.Element:
                        if (reader.Name.Equals("image"))
                        {
                            oneAperioSlideObj = new AperioSlide();
                            imageTagfound = true;
                        }
                        break;
                    case XmlNodeType.Text:
                        if (imageTagfound)
                        {
                            xmlTagValueList.Add(reader.Value);
                        }
                        break;
                    case XmlNodeType.EndElement:
                        if (reader.Name.Equals("image"))
                        {
                            oneAperioSlideObj.setPicName(xmlTagValueList[0]);
                            //oneAperioSlideObj.Imagesize = xmlTagValueList[1];
                            //oneAperioSlideObj.Filesize = xmlTagValueList[2];
                            oneAperioSlideObj.setWidth(xmlTagValueList[3]);
                            oneAperioSlideObj.setHeight(xmlTagValueList[4]);
                            //<depth>1</depth> brauch ich nicht
                            //oneAperioSlideObj.Tilewidth = xmlTagValueList[6];
                            //oneAperioSlideObj.Tileheight = xmlTagValueList[7];
                            oneAperioSlideObj.setDir(folder);

                            //AvaibleSlides.Add(oneAperioSlideObj);
                            listOfAperioSlides.Add(oneAperioSlideObj);
                            imageTagfound = false;
                            xmlTagValueList.Clear();
                        }
                        break;
                }
            }
            return listOfAperioSlides;
        }

    }
}
